package com.service.system.advert;

import com.dao.*;
import com.entity.AdvertVo;
import com.entity.system.*;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.util.Const;
import com.util.LogUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author Alexpy
 * @CreateTime 2018/3/1 17:03
 * @Description
 * @Version 1.0
 */
@Service
public class AdvertServiceImpl implements AdvertService {

    @Autowired
    AdvertMapper advertMapper;

    @Autowired
    UserInfoMapper userInfoMapper;

    @Autowired
    UserAssetsMapper userAssetsMapper;

    @Autowired
    UserCashFlowMapper userCashFlowMapper;

    @Autowired
    AdvertStatisticsMapper advertStatisticsMapper;

    @Autowired
    BannerConfigMapper bannerConfigMapper;

    @Autowired
    NewsCycleMapper newsCycleMapper;

    @Autowired
    PopupAdvertMapper popupAdvertMapper;

    @Override
    public Map<String, Object> getListByCondition(Map<String, Object> params) {
        Map<String, Object> result = new HashMap<>();
        int pageNum = 1;
        int pageSize = 10;
        if (StringUtils.isNotEmpty(params.get("pageNum").toString())) {
            int tmpPageNum = Integer.valueOf(params.get("pageNum").toString());
            if (tmpPageNum > 0) {
                pageNum = tmpPageNum;
            }
        }
        if (StringUtils.isNotEmpty(params.get("pageSize").toString())) {
            int tmpPageSize = Integer.valueOf(params.get("pageSize").toString());
            if (tmpPageSize > 0) {
                pageSize = tmpPageSize;
            }
        }
        PageHelper.startPage(pageNum, pageSize);
        List<Advert> list = new ArrayList<>();
        if(null == params.get("state")){
            list = advertMapper.findByMapMerge(params);
        }else {
            list = advertMapper.selectByCondition(params);
        }
        PageInfo<Advert> pageInfo = new PageInfo<>(list);
        List<Advert> adverts = pageInfo.getList();
        for (Advert a : adverts) {
            a.setPhone(userInfoMapper.findPhoneByUserId(a.getUserId()));
            if(null != a.getAuditUserId()){
                UserInfo userInfo = userInfoMapper.findUserById(a.getAuditUserId());
                if(null != userInfo){
                    a.setAuditUserName(userInfo.getNickName());
                }
            }
        }
        result.put("code", Const.SUCCESS_CODE);
        result.put("list", adverts);
        result.put("page", pageInfo);
        return result;
    }

    @Override
    public Map<String, Object> updateTopFlag(int topFlag,Long id) {
        Map<String,Object> map = new HashMap<String,Object>();
        Advert advert = new Advert();
        advert.setId(id);
        advert.setTopFlag(topFlag);
        int num = advertMapper.updateByPrimaryKeySelective(advert);
        if(num == 1){
            map.put("code",Const.SUCCESS_CODE);
            map.put("message","修改成功");
            map.put("topFlag",topFlag);
        }else {
            map.put("code",Const.ERROR_CODE);
            map.put("message","修改失败");
        }
        return map;
    }

    @Override
    @Transactional
    public Map<String, Object> noThrough(Long id) {
        int code = 2;
        String message = "审核失败";
        Map<String,Object> map = new HashMap<>();

        Subject currentUser = SecurityUtils.getSubject();
        Session session = currentUser.getSession();
        UserInfo user = (UserInfo) session.getAttribute(Const.SESSION_USER);
        Advert advert = advertMapper.selectByPrimaryKey(id);
        if(null != advert){
            advert.setAuditUserId(user.getId());
            advert.setAuditTime(new Date());
            advert.setState(4);//设置状态为4 审核未通过
            int num = advertMapper.updateByPrimaryKeySelective(advert);
            if(num == 1){
                //审核未通过 返还广告币
                //红包金额
                Integer redEnvelopeAmount = advert.getRedEnvelopeAmount();
                //添加判断 金额为0 表示不是福袋 不用返还和记录流水
                if(redEnvelopeAmount > 0){
                    UserAssets userAssets = userAssetsMapper.findUserAssetsByUserId(advert.getUserId());
                    if(null != userAssets){
                        userAssets.setAdvertCoin(userAssets.getAdvertCoin()+redEnvelopeAmount);
                        userAssetsMapper.updateByPrimaryKeySelective(userAssets);
                        //添加用户账户流水
                        UserCashFlow userCashFlow = new UserCashFlow();
                        userCashFlow.setPrice(new BigDecimal(Math.abs(redEnvelopeAmount)));
                        userCashFlow.setCreateTime(new Date());
                        userCashFlow.setCashFlowDirection((byte)1);
                        userCashFlow.setUserId(userAssets.getUserId());
                        userCashFlow.setCashFlowTitle((byte)21);//红包退款
                        userCashFlow.setTriggerTableName("tb_red_envelope");
                        userCashFlow.setTriggerNo(userAssets.getId()+"");
                        userCashFlow.setBalance(new BigDecimal(userAssets.getCashBalance().doubleValue()));
                        userCashFlow.setCashFlowType((byte)2);//广告币
                        int num1 = userCashFlowMapper.insert(userCashFlow);
                        if(num1 == 1){
                            code = 1;
                            message = "审核成功";
                        }
                    }
                }
            }
        }
        map.put("code",code);
        map.put("message",message);
        return map;
    }

    @Override
    @Transactional
    public Map<String, Object> through(Long id) {
        Map<String,Object> map = new HashMap<>();
        int code = 2;
        String message = "审核失败";
        int num = 0;

        Subject currentUser = SecurityUtils.getSubject();
        Session session = currentUser.getSession();
        UserInfo userInfo = (UserInfo) session.getAttribute(Const.SESSION_USER);
        Advert advert = advertMapper.selectByPrimaryKey(id);
        if(null != advert){
            advert.setAuditUserId(userInfo.getId());
            advert.setAuditTime(new Date());
            advert.setState(1);
            int advertType = advert.getAdvertType();
            if(advertType != 5){ //不是首页广告
                num = advertMapper.updateByPrimaryKeySelective(advert);
                if(num == 1){
                    map.put("code",Const.SUCCESS_CODE);
                    map.put("message","审核成功");
                }else {
                    map.put("code",Const.ERROR_CODE);
                    map.put("message","审核失败");
                }
                return map;
            }else { //首页广告
                UserInfo user = userInfoMapper.findUserById(advert.getUserId());
                //发布首页广告:插入广告表advert,更新用户信息（userAssets）中的余额,插入广告明细advertStatistics(advertId、createTime)
                // 判断当前用户是否有置顶首页广告，如果有则更新首页广告，否则插入
                map.put("userId", user.getId());
                map.put("advertType", 5);
                map.put("state", 1);
                List<Advert> adverts = advertMapper.findAdvertByMap(map);
                if(adverts.size() > 0){
                    Advert newAdvert = adverts.get(0);
                    //修改省市区
                    newAdvert.setAdvertConditionProvince(advert.getAdvertConditionProvince());
                    newAdvert.setAdvertConditionArea(advert.getAdvertConditionArea());
                    newAdvert.setAdvertConditionCity(advert.getAdvertConditionCity());
                    newAdvert.setModifyTime(new Date());
                    newAdvert.setRedEnvelopeAmount(newAdvert.getRedEnvelopeAmount()+advert.getRedEnvelopeAmount());
                    newAdvert.setRedEnvelopeCount(newAdvert.getRedEnvelopeCount()+advert.getRedEnvelopeCount());
                    newAdvert.setState(1);
                    num = advertMapper.updateByPrimaryKeySelective(newAdvert); //更新首页广告
                }else {
                    advert.setState(1);
                    advert.setModifyTime(new Date());
                    num = advertMapper.insert(advert);

                    if(num == 1){
                        AdvertStatistics advertStatistics = new AdvertStatistics();
                        advertStatistics.setAdvertId(advert.getId());
                        advertStatistics.setCreateTime(new Date());
                        num = advertStatisticsMapper.insert(advertStatistics);
                        if(num == 1){
                            code = 1;
                            message = "审核成功";
                        }
                    }
                }

            }
        }
        map.put("code",code);
        map.put("message",message);
        return map;
    }

    @Override
    public Map<String, Object> findBannerList(Map<String, String> map) {
        Map<String,Object> map1 = new HashMap<>();
        int pageNum = 1;
        int pageSize = 10;
        if(StringUtils.isNotEmpty(map.get("pageNum"))){
            pageNum = Integer.parseInt(map.get("pageNum"));
        }
        if(StringUtils.isNotEmpty(map.get("pageSize"))){
            pageSize = Integer.parseInt(map.get("pageSize"));
        }
        if(StringUtils.isNotEmpty(map.get("startTime"))){
            map1.put("startTime",map.get("startTime"));
        }
        if(StringUtils.isNotEmpty(map.get("endTime"))){
            map1.put("endTime",map.get("endTime"));
        }
        PageHelper.startPage(pageNum,pageSize);
        List<BannerConfig> list = bannerConfigMapper.findByMap(map1);
        PageInfo<BannerConfig> pageInfo = new PageInfo<>(list);
        map1.clear();
        map1.put("code",Const.SUCCESS_CODE);
        map1.put("message","查询成功");
        map1.put("page",pageInfo);
        map1.put("list",list);
        return map1;
    }

    @Override
    public Map<String, Object> delBanner(String id) {
        Map<String,Object> map = new HashMap<>();
        int num = bannerConfigMapper.deleteByPrimaryKey(Long.parseLong(id));
        if(num == 1){
            map.put("code",Const.SUCCESS_CODE);
            map.put("message","删除成功");
        }else {
            map.put("code",Const.ERROR_CODE);
            map.put("message","删除失败");
        }
        return map;
    }

    @Override
    public Map<String, Object> updateBanner(BannerConfig bannerConfig) {
        Map<String,Object> map = new HashMap<>();
        bannerConfig.setModifyTime(new Date());
        int num = bannerConfigMapper.updateByPrimaryKeySelective(bannerConfig);
        if(num == 1){
            map.put("code",Const.SUCCESS_CODE);
            map.put("message","修改成功");
        }else {
            map.put("code",Const.ERROR_CODE);
            map.put("message","修改失败");
        }
        return map;
    }

    @Override
    public Map<String, Object> addBanner(BannerConfig bannerConfig) {
        Map<String,Object> map = new HashMap<>();
        map.put("bannerType", 1);
        map.put("flag", 1);
        List<BannerConfig> list = bannerConfigMapper.findByMap(map);
        if(null == list){
            bannerConfig.setPicIndex(1);
        }else {
            bannerConfig.setPicIndex(list.size()+1);
        }
        bannerConfig.setCreateTime(new Date());
        bannerConfig.setModifyTime(new Date());
        bannerConfig.setFlag(1);
        int num = bannerConfigMapper.insert(bannerConfig);
        if(num == 1){
            map.put("code",Const.SUCCESS_CODE);
            map.put("message","添加成功");
        }else {
            map.put("code",Const.ERROR_CODE);
            map.put("message","添加失败");
        }
        return map;
    }

    @Override
    public Map<String, Object> findNewsCycleList(Map<String, String> map) {
        Map<String,Object> map1 = new HashMap<>();
        int pageSize = 10;
        int pageNum = 1;
        if(StringUtils.isNotEmpty(map.get("pageSize"))){
            pageSize = Integer.parseInt(map.get("pageSize"));
        }
        if(StringUtils.isNotEmpty(map.get("pageNum"))){
            pageNum = Integer.parseInt(map.get("pageNum"));
        }
        PageHelper.startPage(pageNum,pageSize);
        List<NewsCycle> newsCycles = newsCycleMapper.findByMap(map);
        PageInfo<NewsCycle> pageInfo = new PageInfo<>(newsCycles);
        map1.put("code",Const.SUCCESS_CODE);
        map1.put("message","查询成功");
        map1.put("page",pageInfo);
        map1.put("newsCycles",pageInfo.getList());
        return map1;
    }

    @Override
    public Map<String, Object> updateNewsCycle(NewsCycle newsCycle) {
        Map<String,Object> map = new HashMap<>();
        int num = newsCycleMapper.updateByPrimaryKeySelective(newsCycle);
        if(num == 1){
            map.put("code",Const.SUCCESS_CODE);
            map.put("message","修改成功");
        }else {
            map.put("code",Const.ERROR_CODE);
            map.put("message","修改失败");
        }
        return map;
    }

    @Override
    public Map<String, Object> delNewsCycle(Long id) {
        Map<String,Object> map = new HashMap<>();
        int num = newsCycleMapper.deleteByPrimaryKey(id);
        if(num == 1){
            map.put("code",Const.SUCCESS_CODE);
            map.put("message","删除成功");
        }else {
            map.put("code",Const.ERROR_CODE);
            map.put("message","删除失败");
        }
        return map;
    }

    @Override
    public Map<String, Object> addNewsCycle(NewsCycle newsCycle) {
        Map<String,Object> map = new HashMap<>();
        if(null != newsCycle.getAdvertId()){
            Advert advert = advertMapper.selectByPrimaryKey(newsCycle.getAdvertId());
            if(null != advert){
                newsCycle.setAdvertName(advert.getAdvertName());
                newsCycle.setAdvertType(advert.getAdvertType());
            }
        }
        newsCycle.setCreateTime(new Date());
        newsCycle.setSource(1);
        int num = newsCycleMapper.insertSelective(newsCycle);
        if(num == 1){
            map.put("code",Const.SUCCESS_CODE);
            map.put("message","添加成功");
        }else {
            map.put("code",Const.ERROR_CODE);
            map.put("message","添加失败");
        }
        return map;
    }

    @Override
    public Map<String, Object> findPopupAdvertList(Map<String, String> map) {
        Map<String,Object> map1 = new HashMap<>();
        int pageSize = 10;
        int pageNum = 1;
        if(StringUtils.isNotEmpty(map.get("pageSize"))){
            pageSize = Integer.parseInt(map.get("pageSize"));
        }
        if(StringUtils.isNotEmpty(map.get("pageNum"))){
            pageNum = Integer.parseInt(map.get("pageNum"));
        }
        PageHelper.startPage(pageNum,pageSize);
        List<PopupAdvert> popupAdverts = popupAdvertMapper.findByMap(null);
        PageInfo<PopupAdvert> pageInfo = new PageInfo<>(popupAdverts);
        map1.put("code",Const.SUCCESS_CODE);
        map1.put("message","查询成功");
        map1.put("page",pageInfo);
        map1.put("popupAdverts",pageInfo.getList());
        return map1;
    }

    @Override
    public Map<String, Object> delPopupAdvert(Long id) {
        Map<String,Object> map = new HashMap<>();
        int num = popupAdvertMapper.deleteByPrimaryKey(id);
        if(num == 1){
            map.put("code",Const.SUCCESS_CODE);
            map.put("message","删除成功");
        }else {
            map.put("code",Const.ERROR_CODE);
            map.put("message","删除失败");
        }
        return map;
    }

    @Override
    public Map<String, Object> updatePopupAdvert(PopupAdvert popupAdvert) {
        Map<String,Object> map = new HashMap<>();
        int num = popupAdvertMapper.updateByPrimaryKeySelective(popupAdvert);
        if(num == 1){
            map.put("code",Const.SUCCESS_CODE);
            map.put("message","修改成功");
        }else {
            map.put("code",Const.ERROR_CODE);
            map.put("message","修改成功");
        }
        return map;
    }

    @Override
    public Map<String, Object> addPopupAdvert(PopupAdvert popupAdvert) {
        Map<String,Object> map = new HashMap<>();
        int num = popupAdvertMapper.insertSelective(popupAdvert);
        if(num == 1){
            map.put("code",Const.SUCCESS_CODE);
            map.put("message","添加成功");
        }else {
            map.put("code",Const.ERROR_CODE);
            map.put("message","添加成功");
        }
        return map;
    }

    @Override
    public Map<String, Object> findNewUserAdvert(Map<String, String> map) {
        Map<String,Object> map1 = new HashMap<>();
        int pageSize = 10;
        int pageNum = 1;
        if(StringUtils.isNotEmpty(map.get("pageSize"))){
            pageSize = Integer.parseInt(map.get("pageSize"));
        }
        if(StringUtils.isNotEmpty(map.get("pageNum"))){
            pageNum = Integer.parseInt(map.get("pageNum"));
        }
        PageHelper.startPage(pageNum,pageSize);
        map1.put("advertType",-1);
        map1.put("isDelete",1);
        List<Advert> adverts = advertMapper.findAdvertByMap(map1);
        PageInfo<Advert> pageInfo = new PageInfo<>(adverts);
        map1.clear();
        map1.put("code",Const.SUCCESS_CODE);
        map1.put("message","查询成功");
        map1.put("page",pageInfo);
        map1.put("adverts",pageInfo.getList());
        return map1;
    }

    @Override
    public Map<String, Object> delNewUserAdvert(Long id) {
        Map<String,Object> map = new HashMap<>();
        Advert advert = new Advert();
        advert.setId(id);
        advert.setState(3);
        advert.setIsDelete(0);
        int num = advertMapper.updateByPrimaryKeySelective(advert);
        if(num == 1){
            map.put("code",Const.SUCCESS_CODE);
            map.put("message","删除成功");
        }else {
            map.put("code",Const.ERROR_CODE);
            map.put("message","删除成功");
        }
        return map;
    }

    @Override
    @Transactional
    public Map<String, Object> addNewUserAdvert(Advert advert) {
        Map<String,Object> map = new HashMap<>();
        advert.setAdvertType(-1);
        advert.setAdvertName("新用户福袋");
        advert.setCreateTime(new Date());
        advert.setStartTime(new Date());
        int num = advertMapper.insertSelective(advert);
        //添加广告统计
        if(num == 1){
            AdvertStatistics advertStatistics = new AdvertStatistics();
            advertStatistics.setAdvertId(advert.getId());
            advertStatistics.setCreateTime(new Date());
            int num1 = advertStatisticsMapper.insertSelective(advertStatistics);
            if(num1 == 1){
                map.put("code",Const.SUCCESS_CODE);
                map.put("message","添加成功");
            }else {
                map.put("code",Const.ERROR_CODE);
                map.put("message","添加失败");
            }
        }else {
            map.put("code",Const.ERROR_CODE);
            map.put("message","添加失败");
        }
        return map;
    }

    @Override
    public Map<String, Object> updateNewUserAdvert(Advert advert) {
        Map<String,Object> map = new HashMap<>();
        advert.setModifyTime(new Date());
        int num = advertMapper.updateByPrimaryKeySelective(advert);
        if(num == 1){
            map.put("code",Const.SUCCESS_CODE);
            map.put("message","修改成功");
        }else {
            map.put("code",Const.ERROR_CODE);
            map.put("message","修改失败");
        }
        return map;
    }

    @Override
    public Map<String, Object> findBalance(Long id) {
        Map<String,Object> map = new HashMap<>();
        Advert advert = advertMapper.selectByPrimaryKey(id);
        if(null == advert){
            map.put("code",Const.ERROR_CODE);
            map.put("message","该广告不存在");
            return map;
        }
        if(advert.getState() != 1 && advert.getState() != 2){
            if(advert.getState() == 0){
                map.put("code",Const.ERROR_CODE);
                map.put("message","该广告未审核");
            }else if(advert.getState() == 3) {
                map.put("code",Const.ERROR_CODE);
                map.put("message","该广告已下线");
            }else if(advert.getState() == 4){
                map.put("code",Const.ERROR_CODE);
                map.put("message","该广告审核未通过");
            }else if(advert.getState() == 5){
                map.put("code",Const.ERROR_CODE);
                map.put("message","该广告已超时完成");
            }
            return map;
        }
        AdvertStatistics advertStatistics = advertStatisticsMapper.findByAdvertId(id);
        if(null == advertStatistics){
            map.put("code",Const.ERROR_CODE);
            map.put("message","该广告统计信息不存在");
            return map;
        }
        map.put("code",Const.SUCCESS_CODE);
        map.put("message","查询余额成功");
        map.put("balance",advert.getRedEnvelopeAmount() - advertStatistics.getSendRedEnvelopeAmount());
        return map;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Map<String, Object> offlineAdvert(Long id) {
        Map<String,Object> map = new HashMap<>();
        Advert advert = advertMapper.selectByPrimaryKey(id);
        if(null == advert){
            map.put("code",Const.ERROR_CODE);
            map.put("message","该广告不存在");
            return map;
        }
        if(advert.getState() != 1 && advert.getState() != 2){
            if(advert.getState() == 0){
                map.put("code",Const.ERROR_CODE);
                map.put("message","该广告未审核");
            }else if(advert.getState() == 3) {
                map.put("code",Const.ERROR_CODE);
                map.put("message","该广告已下线");
            }else if(advert.getState() == 4){
                map.put("code",Const.ERROR_CODE);
                map.put("message","该广告审核未通过");
            }else if(advert.getState() == 5){
                map.put("code",Const.ERROR_CODE);
                map.put("message","该广告已超时完成");
            }
            return map;
        }

        AdvertStatistics advertStatistics = advertStatisticsMapper.findByAdvertId(id);
        if(null == advertStatistics){
            map.put("code",Const.ERROR_CODE);
            map.put("message","该广告统计信息不存在");
            return map;
        }

        advert.setState(3);
        advert.setModifyTime(new Date());
        int num = advertMapper.updateByPrimaryKeySelective(advert);
        if(num == 1){
            if(advert.getRedEnvelopeAmount() > 0){
                LogUtil.info("退款红包金额:"+advert.getRedEnvelopeAmount());
                final int balance = advert.getRedEnvelopeAmount() - advertStatistics.getSendRedEnvelopeAmount(); //剩余没有被抢完的金额
                LogUtil.info("退款金额:"+balance+",已领取金额:"+advertStatistics.getSendRedEnvelopeAmount());
                if(balance > 0){
                    UserAssets userAssets = userAssetsMapper.findUserAssetsByUserId(advert.getUserId());
                    if(null == userAssets){
                        map.put("code",Const.ERROR_CODE);
                        map.put("message","用户账户不存在");
                        return map;
                    }
                    userAssets.setAdvertCoin(userAssets.getAdvertCoin() + balance);
                    userAssets.setModifyTime(new Date());
                    if(userAssetsMapper.updateByPrimaryKeySelective(userAssets) == 1){
                        //添加用户账户流水
                        UserCashFlow userCashFlow = new UserCashFlow();
                        userCashFlow.setPrice(new BigDecimal(balance));
                        userCashFlow.setCreateTime(new Date());
                        userCashFlow.setCashFlowDirection((byte) 1);
                        userCashFlow.setUserId(userAssets.getUserId());
                        userCashFlow.setCashFlowTitle((byte) 21); //福袋退款
                        userCashFlow.setTriggerTableName("tb_user_assets");
                        userCashFlow.setTriggerNo(userAssets.getId()+"");
                        userCashFlow.setBalance(new BigDecimal(userAssets.getAdvertCoin()));
                        userCashFlow.setCashFlowType((byte) 2);
                        userCashFlow.setVisible(1);
                        if(userCashFlowMapper.insert(userCashFlow) == 1){
                            map.put("code",Const.SUCCESS_CODE);
                            map.put("message","下线成功");
                        }else {
                            LogUtil.info("添加用户账户流水失败");
                            throw new RuntimeException();
                        }
                    }else {
                        LogUtil.info("修改用户账户失败");
                        throw new RuntimeException();
                    }
                }else {
                    map.put("code",Const.SUCCESS_CODE);
                    map.put("message","下线成功");
                }
            }else {
                map.put("code",Const.SUCCESS_CODE);
                map.put("message","下线成功");
            }
        }else {
            map.put("code",Const.ERROR_CODE);
            map.put("message","下线失败");
        }

        return map;
    }
}
